#include "quixml.h"

#include <QRect>
#include <QFont>
#include <QDateTime>
#include <QColor>

QVariant XMLValue::value()
{
    return m_value;
}

void XMLValue::setValue(QVariant value)
{
    m_value=value;
}


void XMLStringValue::read(QXmlStreamReader &r)
{
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            m_value=r.text().toString();
            break;
        default:
            break;
        }
    }
}

void XMLStringValue::write(QXmlStreamWriter &w)
{
    w.writeStartElement("","string");

    w.writeCharacters(m_value.toString());

    w.writeEndElement();
}

void XMLSizeValue::write(QXmlStreamWriter &w)
{
    QSize sz=m_value.toSize();
    w.writeStartElement("","size");

    w.writeStartElement("","width");
    w.writeCharacters(QString::number(sz.width()));
    w.writeEndElement();

    w.writeStartElement("","height");
    w.writeCharacters(QString::number(sz.height()));
    w.writeEndElement();

    w.writeEndElement();
}

void XMLSizeValue::read(QXmlStreamReader &r)
{
    QSize sz=QSize();
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            QString name=r.name().toString();
            if(name=="width")
            {
                sz.setWidth(readSubValue(r));
            }
            else if(name=="height")
            {
                sz.setHeight(readSubValue(r));
            }
        }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value=sz;
}

int XMLSizeValue::readSubValue(QXmlStreamReader &r)
{
    int value=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            value=r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return value;
}

void XMLRectValue::read(QXmlStreamReader &r)
{
    QRect re=QRect();
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            QString name=r.name().toString();
            if(name=="x")
            {
                re.setX(readSubValue(r));
            }
            else if(name=="y")
            {
                re.setY(readSubValue(r));
            }
            else if(name=="width")
            {
                re.setWidth(readSubValue(r));
            }
            else if(name=="height")
            {
                re.setHeight(readSubValue(r));
            }
        }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value=re;
}

int XMLRectValue::readSubValue(QXmlStreamReader &r)
{
    int value=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            value=r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return value;
}

void XMLRectValue::write(QXmlStreamWriter &w)
{
    QRect re=m_value.toRect();
    w.writeStartElement("","rect");

    w.writeStartElement("","x");
    w.writeCharacters(QString::number(re.x()));
    w.writeEndElement();

    w.writeStartElement("","y");
    w.writeCharacters(QString::number(re.y()));
    w.writeEndElement();

    w.writeStartElement("","width");
    w.writeCharacters(QString::number(re.width()));
    w.writeEndElement();

    w.writeStartElement("","height");
    w.writeCharacters(QString::number(re.height()));
    w.writeEndElement();

    w.writeEndElement();
}

void XMLPaddingValue::read(QXmlStreamReader &r)
{
    tagPaddingInfo padd;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            QString name=r.name().toString();
            if(name=="left")
            {
                padd.m_left=readSubValue(r);
            }
            else if(name=="top")
            {
                padd.m_top=readSubValue(r);
            }
            else if(name=="right")
            {
                padd.m_right=readSubValue(r);
            }
            else if(name=="bottom")
            {
                padd.m_bottom=readSubValue(r);
            }
        }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<tagPaddingInfo>(padd);
}

int XMLPaddingValue::readSubValue(QXmlStreamReader &r)
{
    int value=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            value=r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return value;
}

void XMLPaddingValue::write(QXmlStreamWriter &w)
{
    tagPaddingInfo padd=m_value.value<tagPaddingInfo>();
    w.writeStartElement("","padding");

    w.writeStartElement("","left");
    w.writeCharacters(QString::number(padd.m_left));
    w.writeEndElement();

    w.writeStartElement("","top");
    w.writeCharacters(QString::number(padd.m_top));
    w.writeEndElement();

    w.writeStartElement("","right");
    w.writeCharacters(QString::number(padd.m_right));
    w.writeEndElement();

    w.writeStartElement("","bottom");
    w.writeCharacters(QString::number(padd.m_bottom));
    w.writeEndElement();

    w.writeEndElement();
}

void XMLIntValue::read(QXmlStreamReader &r)
{
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            m_value=r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
}

void XMLIntValue::write(QXmlStreamWriter &w)
{
    w.writeStartElement("","number");
    w.writeCharacters(QString::number(m_value.toInt()));
    w.writeEndElement();
}

void XMLFloatValue::read(QXmlStreamReader &r)
{
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            m_value=r.text().toString().toDouble();
            break;
        default:
            break;
        }
    }
}

void XMLFloatValue::write(QXmlStreamWriter &w)
{
    w.writeStartElement("","float");
    w.writeCharacters(QString::number(m_value.toDouble()));
    w.writeEndElement();
}

void XMLBoolValue::read(QXmlStreamReader &r)
{
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            m_value=r.text().toString()=="true";
            break;
        default:
            break;
        }
    }
}

void XMLBoolValue::write(QXmlStreamWriter &w)
{
    w.writeStartElement("","bool");
    w.writeCharacters(m_value.toBool()?"true":"false");
    w.writeEndElement();
}

void XMLFontValue::write(QXmlStreamWriter &w)
{
    QFont f=m_value.value<QFont>();
    w.writeStartElement("","font");

    w.writeStartElement("","family");
    w.writeCharacters(f.family());
    w.writeEndElement();

    w.writeStartElement("","pointSize");
    w.writeCharacters(QString::number(f.pointSize()));
    w.writeEndElement();

    w.writeStartElement("","bold");
    w.writeCharacters(f.bold()?"true":"false");
    w.writeEndElement();

    w.writeStartElement("","italic");
    w.writeCharacters(f.italic()?"true":"false");
    w.writeEndElement();

    w.writeStartElement("","underline");
    w.writeCharacters(f.underline()?"true":"false");
    w.writeEndElement();

    w.writeStartElement("","strikeOut");
    w.writeCharacters(f.strikeOut()?"true":"false");
    w.writeEndElement();

    w.writeEndElement();
}

void XMLFontValue::read(QXmlStreamReader &r)
{
    QFont f;
    f=m_value.value<QFont>();
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="family")
            {
                f.setFamily(readSubValue(r));
            }
            else if(name=="pointSize")
            {
                f.setPointSize(readSubValue(r).toInt());
            }
            else if(name=="bold")
            {
                f.setBold(readSubValue(r)=="true");
            }
            else if(name=="italic")
            {
                f.setItalic(readSubValue(r)=="true");
            }
            else if(name=="underline")
            {
                f.setUnderline(readSubValue(r)=="true");
            }
            else if(name=="strikeOut")
            {
                f.setStrikeOut(readSubValue(r)=="true");
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<QFont>(f);
}

QString XMLFontValue::readSubValue(QXmlStreamReader &r)
{
    QString value;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            value=r.text().toString();
            break;
        default:
            break;
        }
    }
    return value;
}


void XMLComboItemsValue::write(QXmlStreamWriter &w)
{
    ComboItems items=m_value.value<ComboItems>();
    w.writeStartElement("","ComboBox_items");

    tagComboItem item;
    for(int i=0;i<items.size();i++)
    {
        item=items.at(i);
        w.writeStartElement("","item");
        w.writeAttribute("text",item.m_text);
        w.writeAttribute("icon",item.m_icon);
        w.writeEndElement();
    }

    w.writeEndElement();
}

void XMLComboItemsValue::read(QXmlStreamReader &r)
{
    ComboItems items;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="item")
            {
                items.append(readSubItem(r));
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<ComboItems>(items);
}

tagComboItem XMLComboItemsValue::readSubItem(QXmlStreamReader &r)
{
    tagComboItem item;
    foreach(const QXmlStreamAttribute &attribute,r.attributes())
    {
        if(attribute.name().toString()=="text")
        {
            item.m_text=attribute.value().toString();
        }
        else if(attribute.name().toString()=="icon")
        {
            item.m_icon=attribute.value().toString();
        }
    }
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }
    return item;
}


void XMLTimeValue::read(QXmlStreamReader &r)
{
    QTime ti;
    int h,m,s;
    h=m=s=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="hour")
            {
                h=readSubItem(r);
            }
            else if(name=="minute")
            {
                m=readSubItem(r);
            }
            else if(name=="second")
            {
                s=readSubItem(r);
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    ti.setHMS(h,m,s);
    m_value=ti;
}

void XMLTimeValue::write(QXmlStreamWriter &w)
{
    QTime ti=m_value.toTime();
    w.writeStartElement("","time");

    w.writeStartElement("hour");
    w.writeCharacters(QString::number(ti.hour()));
    w.writeEndElement();

    w.writeStartElement("minute");
    w.writeCharacters(QString::number(ti.minute()));
    w.writeEndElement();

    w.writeStartElement("second");
    w.writeCharacters(QString::number(ti.second()));
    w.writeEndElement();

    w.writeEndElement();
}

int XMLTimeValue::readSubItem(QXmlStreamReader &r)
{
    int ret=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return ret;
}

void XMLDateValue::read(QXmlStreamReader &r)
{
    QDate dt;
    int y,m,d;
    y=m=d=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="year")
            {
                y=readSubItem(r);
            }
            else if(name=="month")
            {
                m=readSubItem(r);
            }
            else if(name=="day")
            {
                d=readSubItem(r);
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    dt.setDate(y,m,d);
    m_value=dt;
}

void XMLDateValue::write(QXmlStreamWriter &w)
{
    QDate dt=m_value.toDate();
    w.writeStartElement("","date");

    w.writeStartElement("year");
    w.writeCharacters(QString::number(dt.year()));
    w.writeEndElement();

    w.writeStartElement("month");
    w.writeCharacters(QString::number(dt.month()));
    w.writeEndElement();

    w.writeStartElement("day");
    w.writeCharacters(QString::number(dt.day()));
    w.writeEndElement();

    w.writeEndElement();
}

int XMLDateValue::readSubItem(QXmlStreamReader &r)
{
    int ret=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return ret;
}


void XMLDateTimeValue::read(QXmlStreamReader &r)
{
    QDateTime dt;
    int y,m,d;
    int h,min,s;
    y=m=d=h=min=s=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="year")
            {
                y=readSubItem(r);
            }
            else if(name=="month")
            {
                m=readSubItem(r);
            }
            else if(name=="day")
            {
                d=readSubItem(r);
            }
            else if(name=="hour")
            {
                h=readSubItem(r);
            }
            else if(name=="minute")
            {
                min=readSubItem(r);
            }
            else if(name=="second")
            {
                s=readSubItem(r);
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    dt.setDate(QDate(y,m,d));
    dt.setTime(QTime(h,min,s));
    m_value=dt;
}

void XMLDateTimeValue::write(QXmlStreamWriter &w)
{
    QDateTime dt=m_value.toDateTime();
    w.writeStartElement("","datetime");

    w.writeStartElement("year");
    w.writeCharacters(QString::number(dt.date().year()));
    w.writeEndElement();

    w.writeStartElement("month");
    w.writeCharacters(QString::number(dt.date().month()));
    w.writeEndElement();

    w.writeStartElement("day");
    w.writeCharacters(QString::number(dt.date().day()));
    w.writeEndElement();

    w.writeStartElement("hour");
    w.writeCharacters(QString::number(dt.time().hour()));
    w.writeEndElement();

    w.writeStartElement("minute");
    w.writeCharacters(QString::number(dt.time().minute()));
    w.writeEndElement();

    w.writeStartElement("second");
    w.writeCharacters(QString::number(dt.time().second()));
    w.writeEndElement();

    w.writeEndElement();
}

int XMLDateTimeValue::readSubItem(QXmlStreamReader &r)
{
    int ret=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return ret;
}

void XMLColorValue::read(QXmlStreamReader &r)
{
    tagColorInfo c;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="red")
            {
                c.m_color.setRed(readSubItem(r));
            }
            else if(name=="green")
            {
                c.m_color.setGreen(readSubItem(r));
            }
            else if(name=="blue")
            {
                c.m_color.setBlue(readSubItem(r));
            }
            else if(name=="alpha")
            {
                c.m_color.setAlpha(readSubItem(r));
            }
            else if(name=="type")
            {
                c.m_type=readSubItem(r);
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<tagColorInfo>(c);
}

void XMLColorValue::write(QXmlStreamWriter &w)
{
    tagColorInfo c=m_value.value<tagColorInfo>();
    w.writeStartElement("","color");

    w.writeStartElement("red");
    w.writeCharacters(QString::number(c.m_color.red()));
    w.writeEndElement();

    w.writeStartElement("green");
    w.writeCharacters(QString::number(c.m_color.green()));
    w.writeEndElement();

    w.writeStartElement("blue");
    w.writeCharacters(QString::number(c.m_color.blue()));
    w.writeEndElement();

    w.writeStartElement("alpha");
    w.writeCharacters(QString::number(c.m_color.alpha()));
    w.writeEndElement();

    w.writeStartElement("type");
    w.writeCharacters(QString::number(c.m_type));
    w.writeEndElement();

    w.writeEndElement();
}

int XMLColorValue::readSubItem(QXmlStreamReader &r)
{
    int ret=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return ret;
}

void XMLBorderValue::read(QXmlStreamReader &r)
{
    tagBorderInfo c;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="red")
            {
                c.m_color.setRed(readSubItem(r));
            }
            else if(name=="green")
            {
                c.m_color.setGreen(readSubItem(r));
            }
            else if(name=="blue")
            {
                c.m_color.setBlue(readSubItem(r));
            }
            else if(name=="alpha")
            {
                c.m_color.setAlpha(readSubItem(r));
            }
            else if(name=="type")
            {
                c.m_border_type=readText(r);
            }
            else if(name=="width")
            {
                c.m_border_width=readSubItem(r);
            }
            else if(name=="null")
            {
                c.m_isNull=(readText(r)!="false");
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<tagBorderInfo>(c);
}

void XMLBorderValue::write(QXmlStreamWriter &w)
{
    tagBorderInfo c=m_value.value<tagBorderInfo>();
    w.writeStartElement("","border");

    w.writeStartElement("red");
    w.writeCharacters(QString::number(c.m_color.red()));
    w.writeEndElement();

    w.writeStartElement("green");
    w.writeCharacters(QString::number(c.m_color.green()));
    w.writeEndElement();

    w.writeStartElement("blue");
    w.writeCharacters(QString::number(c.m_color.blue()));
    w.writeEndElement();

    w.writeStartElement("alpha");
    w.writeCharacters(QString::number(c.m_color.alpha()));
    w.writeEndElement();

    w.writeStartElement("type");
    w.writeCharacters(c.m_border_type);
    w.writeEndElement();

    w.writeStartElement("width");
    w.writeCharacters(QString::number(c.m_border_width));
    w.writeEndElement();

    w.writeStartElement("null");
    w.writeCharacters(c.m_isNull?"true":"false");
    w.writeEndElement();

    w.writeEndElement();
}

int XMLBorderValue::readSubItem(QXmlStreamReader &r)
{
    int ret=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return ret;
}

QString XMLBorderValue::readText(QXmlStreamReader &r)
{
    QString ret;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString();
            break;
        default:
            break;
        }
    }
    return ret;
}

void XMLImageValue::read(QXmlStreamReader &r)
{
    tagImageInfo info;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="name")
            {
                info.m_name=readText(r);
            }
            else if(name=="type")
            {
                info.m_type=readInt(r);
            }
            else if(name=="left")
            {
                info.m_left=readInt(r);
            }
            else if(name=="right")
            {
                info.m_right=readInt(r);
            }
            else if(name=="top")
            {
                info.m_top=readInt(r);
            }
            else if(name=="bottom")
            {
                info.m_bottom=readInt(r);
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<tagImageInfo>(info);
}

int XMLImageValue::readInt(QXmlStreamReader &r)
{
    int ret=0;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString().toInt();
            break;
        default:
            break;
        }
    }
    return ret;
}

QString XMLImageValue::readText(QXmlStreamReader &r)
{
    QString ret;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            ret= r.text().toString();
            break;
        default:
            break;
        }
    }
    return ret;
}

void XMLImageValue::write(QXmlStreamWriter &w)
{
    tagImageInfo info=m_value.value<tagImageInfo>();
    w.writeStartElement("","image");

    w.writeStartElement("name");
    w.writeCharacters(info.m_name);
    w.writeEndElement();

    w.writeStartElement("type");
    w.writeCharacters(QString::number(info.m_type));
    w.writeEndElement();

    w.writeStartElement("left");
    w.writeCharacters(QString::number(info.m_left));
    w.writeEndElement();

    w.writeStartElement("right");
    w.writeCharacters(QString::number(info.m_right));
    w.writeEndElement();

    w.writeStartElement("top");
    w.writeCharacters(QString::number(info.m_top));
    w.writeEndElement();

    w.writeStartElement("bottom");
    w.writeCharacters(QString::number(info.m_bottom));
    w.writeEndElement();

    w.writeEndElement();
}


void XMLMemeryDataValue::write(QXmlStreamWriter &w)
{
    MemeryValueItems items=m_value.value<MemeryValueItems>();
    w.writeStartElement("","memeryValue_items");

    tagMemeryValueInfo item;
    for(int i=0;i<items.size();i++)
    {
        item=items.at(i);
        w.writeStartElement("","item");
        w.writeAttribute("property",item.m_propertyName);
        w.writeAttribute("value",item.m_valueName);
        w.writeAttribute("script",item.m_script);
        w.writeEndElement();
    }

    w.writeEndElement();
}

void XMLMemeryDataValue::read(QXmlStreamReader &r)
{
    MemeryValueItems items;
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
        {
            const QString name=r.name().toString();
            if(name=="item")
            {
                items.append(readSubItem(r));
            }
        }
             break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        case QXmlStreamReader::Characters:
            break;
        default:
            break;
        }
    }
    m_value.setValue<MemeryValueItems>(items);
}

tagMemeryValueInfo XMLMemeryDataValue::readSubItem(QXmlStreamReader &r)
{
    tagMemeryValueInfo item;
    foreach(const QXmlStreamAttribute &attribute,r.attributes())
    {
        if(attribute.name().toString()=="property")
        {
            item.m_propertyName=attribute.value().toString();
        }
        else if(attribute.name().toString()=="value")
        {
            item.m_valueName=attribute.value().toString();
        }
        else if(attribute.name().toString()=="script")
        {
            item.m_script=attribute.value().toString();
        }
    }
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }
    return item;
}


XMLProperty::XMLProperty():
    m_value(NULL)
{

}

QVariant XMLProperty::value()
{
    if(m_value==NULL)
    {
        return QVariant();
    }

    return m_value->value();
}

void XMLProperty::setValue(QVariant value)
{
    if(m_value==NULL)
    {
        return;
    }
    m_value->setValue(value);
}

void XMLProperty::setType(const QString &type)
{
    if(m_value!=NULL)
    {
        delete m_value;
    }
    m_value=createValue(type);
}

QString XMLProperty::type()
{
    return m_type;
}

void XMLProperty::read(QXmlStreamReader &r)
{
    if(m_value!=NULL)
    {
        delete m_value;
        m_value=NULL;
    }
    m_propertyName="";
    foreach(const QXmlStreamAttribute &attribute,r.attributes())
    {
        QStringRef name=attribute.name();
        if(name==QLatin1String("name"))
        {
            m_propertyName=attribute.value().toString();
        }
    }
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            m_value=createValue(r.name().toString());

            if(m_value!=NULL)
            {
                m_value->read(r);
            }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }
    if(m_propertyName=="")
    {
        r.raiseError("Can not find property name!");
    }
}

void XMLProperty::write(QXmlStreamWriter &w)
{
    if(m_value==NULL)
    {
        return;
    }
    w.writeStartElement("","property");

    w.writeAttribute("name",m_propertyName);

    m_value->write(w);

    w.writeEndElement();
}

XMLValue* XMLProperty::createValue(const QString type)
{
    m_type="";
    XMLValue *ret=NULL;

    if(type=="string")
    {
        ret=new XMLStringValue;
    }
    else if(type=="rect")
    {
        ret=new XMLRectValue;
    }
    else if(type=="size")
    {
        ret=new XMLSizeValue;
    }
    else if(type=="number")
    {
        ret=new XMLIntValue;
    }
    else if(type=="float")
    {
        ret=new XMLFloatValue;
    }
    else if(type=="bool")
    {
        ret=new XMLBoolValue;
    }
    else if(type=="font")
    {
        ret=new XMLFontValue;
    }
    else if(type=="ComboBox_items")
    {
        ret=new XMLComboItemsValue;
    }
    else if(type=="time")
    {
        ret=new XMLTimeValue;
    }
    else if(type=="date")
    {
        ret=new XMLDateValue;
    }
    else if(type=="datetime")
    {
        ret=new XMLDateTimeValue;
    }
    else if(type=="color")
    {
        ret=new XMLColorValue;
    }
    else if(type=="image")
    {
        ret=new XMLImageValue;
    }
    else if(type=="memeryValue_items")
    {
        ret=new XMLMemeryDataValue;
    }
    else if(type=="padding")
    {
        ret=new XMLPaddingValue;
    }
    else if(type=="border")
    {
        ret=new XMLBorderValue;
    }

    if(ret!=NULL)
    {
        m_type=type;
    }
    return ret;
}

QString XMLProperty::propertyName()
{
    return m_propertyName;
}

void XMLProperty::setPropertyName(const QString &name)
{
    m_propertyName=name;
}


XMLWidget::XMLWidget(XMLWidget *parent):
    m_parent(parent)
{
    if(m_parent!=NULL)
    {
        m_parent->m_children.append(this);
    }
}

XMLWidget::~XMLWidget()
{
    qDeleteAll(m_propertys);
    m_propertys.clear();
    //qDeleteAll(m_children);
    while(m_children.size()>0)
    {
        delete m_children.first();
        m_children.removeFirst();
    }
}

void XMLWidget::read(QXmlStreamReader &r)
{
    m_attributes.clear();
    qDeleteAll(m_propertys);
    m_propertys.clear();
    foreach(const QXmlStreamAttribute &attribute,r.attributes())
    {
        m_attributes.insert(attribute.name().toString(),attribute.value().toString());
    }
    for(bool finished=false;!finished && !r.hasError();)
    {
        switch(r.readNext())
        {
        case QXmlStreamReader::StartElement:
            if(r.name()=="property")
            {
                XMLProperty *p=addProperty();
                p->read(r);
            }
            else if(r.name()=="widget")
            {
                XMLWidget *wid=new XMLWidget(this);
                wid->read(r);
            }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }
    if(m_attributes.value("class")=="")
    {
        r.raiseError("Can not find class type!");
    }
}

void XMLWidget::write(QXmlStreamWriter &w)
{
    w.writeStartElement("","widget");

    QMapIterator<QString,QString>   i(m_attributes);

    while(i.hasNext())
    {
        i.next();
        w.writeAttribute(i.key(),i.value());
    }

    for(int i=0;i<m_propertys.size();i++)
    {
        m_propertys.at(i)->write(w);
    }

    foreach(XMLWidget *wid,m_children)
    {
        wid->write(w);
    }

    w.writeEndElement();
}

XMLProperty *XMLWidget::addProperty()
{
    XMLProperty *property;
    property=new XMLProperty;

    m_propertys.append(property);
    return property;
}

QList<XMLProperty*> XMLWidget::propertys()
{
    return m_propertys;
}

QList<XMLWidget*>  XMLWidget::children()
{
    return m_children;
}

void XMLWidget::setAttribute(const QString &key, const QString &value)
{
    m_attributes.insert(key,value);
}

QString XMLWidget::attribute(const QString &key, const QString &def)
{
    return m_attributes.value(key,def);
}
